/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openFuyao is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

package clean

import (
	"os"
	"path/filepath"
	"testing"

	"env-check/pkg/config"
	"env-check/pkg/logger"
)

func TestCleanerExecuteDryRun(t *testing.T) {
	tempDir := setupTestDir(t)
	defer os.RemoveAll(tempDir)

	cfg := &config.AppConfig{
		Mode:        config.ModeClean,
		Paths:       []string{tempDir},
		CleanDryRun: true,
		CleanAuto:   true,
	}
	log := logger.NewLogger("")
	cleaner := NewCleaner(cfg, log)

	result, err := cleaner.Execute()
	assertNoError(t, err)

	// 验证文件仍然存在（dry run）
	_, err = os.Stat(filepath.Join(tempDir, "test.txt"))
	assertNoError(t, err)

	assertEqual(t, len(result.Deleted) > 0, true)
}

func TestCleanerExecuteActualDelete(t *testing.T) {
	// 注意：这里不defer删除，因为要测试删除操作
	tempDir := setupTestDir(t)

	cfg := &config.AppConfig{
		Mode:        config.ModeClean,
		Paths:       []string{tempDir},
		CleanDryRun: false,
		CleanAuto:   true,
	}
	log := logger.NewLogger("")
	cleaner := NewCleaner(cfg, log)

	result, err := cleaner.Execute()
	assertNoError(t, err)

	// 验证文件已被删除
	_, err = os.Stat(tempDir)
	assertError(t, err) // 应该出错，因为目录已被删除

	assertEqual(t, len(result.Deleted) > 0, true)
}

func TestCleanPathFile(t *testing.T) {
	tempDir := setupTestDir(t)
	defer os.RemoveAll(tempDir)

	cleaner, result := createDefaultCleaner()

	cleaner.cleanPath(tempDir, result)
	assertEqual(t, len(result.Deleted) > 0, true)
}

func TestCleanPathNonExistent(t *testing.T) {
	cleaner, result := createDefaultCleaner()

	cleaner.cleanPath("/non/existent/path", result)
	assertEqual(t, len(result.Skipped) > 0, true)
}

func TestShouldDeleteAutoMode(t *testing.T) {
	cfg := &config.AppConfig{
		CleanAuto: true,
	}
	log := logger.NewLogger("")
	cleaner := NewCleaner(cfg, log)

	fileInfo := config.FileInfo{Path: "/test"}
	result := cleaner.shouldDelete(fileInfo)
	assertEqual(t, result, true)
}

func TestShouldDeleteDryRun(t *testing.T) {
	cfg := &config.AppConfig{
		CleanAuto:   false,
		CleanDryRun: true,
	}
	log := logger.NewLogger("")
	cleaner := NewCleaner(cfg, log)

	fileInfo := config.FileInfo{Path: "/test"}
	result := cleaner.shouldDelete(fileInfo)
	assertEqual(t, result, true)
}

// 辅助函数
func setupTestDir(t *testing.T) string {
	tempDir, err := os.MkdirTemp("", "clean-test-*")
	assertNoError(t, err)

	testFile := filepath.Join(tempDir, "test.txt")
	err = os.WriteFile(testFile, []byte("test content"), config.FileMode)
	assertNoError(t, err)

	return tempDir
}

func createDefaultCleaner() (*FileCleaner, *config.CleanResult) {
	cfg := &config.AppConfig{
		Mode:        config.ModeClean,
		CleanDryRun: true,
		CleanAuto:   true,
	}
	log := logger.NewLogger("")
	cleaner := NewCleaner(cfg, log)

	result := &config.CleanResult{
		Deleted: make([]config.FileInfo, 0),
		Failed:  make([]config.FileInfo, 0),
		Skipped: make([]config.FileInfo, 0),
	}
	return cleaner, result
}

func assertError(t *testing.T, err error) {
	t.Helper()
	if err == nil {
		t.Fatal("Expected error, got nil")
	}
}

func assertNoError(t *testing.T, err error) {
	t.Helper()
	if err != nil {
		t.Fatalf("Expected no error, got: %v", err)
	}
}

func assertEqual(t *testing.T, actual, expected interface{}) {
	t.Helper()
	if actual != expected {
		t.Fatalf("Expected %v, got %v", expected, actual)
	}
}
